﻿// --------------------------------------------------------------------------------------------------------------------
// <copyright file="MessageManagerImpl.cs" company="Rabid Dog Labs">
//   Rabid Dog Labs
// </copyright>
// <summary>
//   Defines the MessageManagerImpl type.
// </summary>
// --------------------------------------------------------------------------------------------------------------------

using System;
using log4net;
using TeamCommunitySolution.Modules.Messaging.Requests;
using TeamCommunitySolution.Modules.Messaging.Responses;
using TeamCommunitySolution.Repositories.Base;
using TeamCommunitySolution.Domain.DataLayer.Base;
using TeamCommunitySolution.Modules.Shared;

namespace TeamCommunitySolution.Modules.Messaging
{
    /// <summary>
    /// Message Manager Implementation
    /// </summary>
    public class MessageManagerImpl : MessageManager
    {
        /// <summary>
        /// The logger instance.
        /// </summary>
        private static readonly ILog _log = LogManager.GetLogger(typeof(MessageManagerImpl));

        /// <summary>
        /// The repository reference.
        /// </summary>
        private BaseRepository baseRepo;

        /// <summary>
        /// Prevents a default instance of the <see cref="MessageManagerImpl"/> class from being created.
        /// </summary>
        private MessageManagerImpl()
        {
        }

        /// <summary>
        /// Creates the instance.
        /// </summary>
        /// <param name="baseRepository">The base repository.</param>
        /// <returns>Message Manager.</returns>
        public static MessageManager CreateInstance(BaseRepository baseRepository)
        {
            MessageManagerImpl output = new MessageManagerImpl();
            output.baseRepo = baseRepository;

            return output;
        }

        /// <summary>
        /// Sends the private message.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Message Response</returns>
        public MessageResponse SendPrivateMessage(MessageRequest request)
        {
            if (request == null)
            {
                throw new InvalidMessageRequestException("The message request object cannot be null");
            }

            if (string.IsNullOrEmpty(request.Title))
            {
                throw new InvalidMessageRequestException("The message request must contain a title");
            }

            if (string.IsNullOrEmpty(request.Content))
            {
                throw new InvalidMessageRequestException("The message request must contain a body");
            }

            if (string.IsNullOrEmpty(request.UserFromId))
            {
                throw new InvalidMessageRequestException("The message request must contain the id of the user it is from");
            }


            SystemUser userFrom = this.baseRepo.GetUserByField("Id", request.UserFromId);
            SystemUser userTo = this.baseRepo.GetUserByField("Id", request.UserToId);

            MessageInbox messageIn = new MessageInbox();
            messageIn.DateSent = DateTime.Now;
            messageIn.IsRead = false;
            messageIn.MessageContent = request.Content;
            messageIn.Title = request.Title;
            messageIn.UserFrom = userFrom;
            messageIn.UserTo = userTo;

            MessageOutbox messageOut = new MessageOutbox();
            messageOut.DateSent = DateTime.Now;
            messageOut.IsRead = false;
            messageOut.MessageContent = request.Content;
            messageOut.Title = request.Title;
            messageOut.UserFrom = userFrom;
            messageOut.UserTo = userTo;

            MessageResponse response = new MessageResponse();

            try
            {
                this.baseRepo.SaveMessage(messageIn, messageOut);

                response.MessageInId = messageIn.Id;
                response.MessageOutId = messageOut.Id;
                response.Status = OperationStatus.Success;
            }
            catch (BaseRepositoryException e)
            {
                response.Status = OperationStatus.Failure;
                response.Message = string.Format("Incomplete message send {0} : {1}", request.Title, e.Message);
                response.Exception = e;
                _log.Error(response.Message, e);
            }

            return response;
        }

        /// <summary>
        /// Gets the message inbox item.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Message Response.</returns>
        public MessageResponse GetMessageInboxItem(MessageRequest request)
        {
            if (request == null)
            {
                throw new InvalidMessageRequestException("The message request object cannot be null");
            }

            if (string.IsNullOrEmpty(request.Id))
            {
                throw new InvalidMessageRequestException("The message request must contain the id of the requested message");
            }

            MessageResponse response = new MessageResponse();

            try
            {
                response.MessageInbox = this.baseRepo.GetInboxMessage(request.Id);
                response.Status = OperationStatus.Success;
            }
            catch (BaseRepositoryException e)
            {
                response.Status = OperationStatus.Failure;
                response.Message = string.Format("Could not find message inbox  {0} : {1}", request.Id, e.Message);
                response.Exception = e;
                _log.Error(response.Message, e);
            }

            return response;
        }

        /// <summary>
        /// Gets the message outbox item.
        /// </summary>
        /// <param name="request">The request.</param>
        /// <returns>Message Response</returns>
        public MessageResponse GetMessageOutboxItem(MessageRequest request)
        {
            if (request == null)
            {
                throw new InvalidMessageRequestException("The message request object cannot be null");
            }

            if (string.IsNullOrEmpty(request.Id))
            {
                throw new InvalidMessageRequestException("The message request must contain the id of the requested message");
            }

            MessageResponse response = new MessageResponse();

            try
            {
                response.MessageOutbox = this.baseRepo.GetOutboxMessage(request.Id);
                response.Status = OperationStatus.Success;
            }
            catch (BaseRepositoryException e)
            {
                response.Status = OperationStatus.Failure;
                response.Message = string.Format("Could not find message outbox  {0} : {1}", request.Id, e.Message);
                response.Exception = e;
                _log.Error(response.Message, e);
            }

            return response;
        }
    }
}
